#include "GMDirectx9.h"


GMDirectx9::GMDirectx9( HWND hwnd )
{
	m_running = false;
	m_d3d9 = 0;
	memset( &m_d3dparameter, 0, sizeof( m_d3dparameter ) );
	m_depthstencilformat = D3DFMT_D16;
	m_colorformat = D3DFMT_R5G6B5;
	m_multisampling = D3DMULTISAMPLE_NONE;
	m_vertexprocessing = D3DCREATE_HARDWARE_VERTEXPROCESSING; //D3DCREATE_SOFTWARE_VERTEXPROCESSING;

	m_d3dDevice9 = 0;


	m_running = initialize( hwnd );
}


GMDirectx9::~GMDirectx9( void )
{
	if( m_d3dDevice9 )
	{
		m_d3dDevice9->Release();
		m_d3dDevice9 = 0;
	}

	if( m_d3d9 )
	{
		m_d3d9->Release();
		m_d3d9 = 0;
	}
}


bool GMDirectx9::initialize( HWND hwnd )
{
	if( !( m_d3d9 = Direct3DCreate9( D3D_SDK_VERSION ) ) )
	{
		//! failed, create direct3d-9
		return false;
	}


	//! fullscreen
	m_d3dparameter.Windowed = true;
	//! throw away last frame
	m_d3dparameter.SwapEffect = D3DSWAPEFFECT_DISCARD;
	//! own depth/stencil format
	m_d3dparameter.EnableAutoDepthStencil = true;
	//! depth stencil format
	m_d3dparameter.AutoDepthStencilFormat = m_depthstencilformat;
	//! window handle
	m_d3dparameter.hDeviceWindow = hwnd;
	//! screen width
	m_d3dparameter.BackBufferWidth = 800;
	//! screen height
	m_d3dparameter.BackBufferHeight = 600;
	//! color depth
	m_d3dparameter.BackBufferFormat = m_colorformat;
	//! anti-aliasing
	m_d3dparameter.MultiSampleType = m_multisampling;


	if( FAILED( m_d3d9->CreateDevice( D3DADAPTER_DEFAULT,
									  D3DDEVTYPE_HAL,
									  hwnd,
									  m_vertexprocessing,
									  &m_d3dparameter,
									  &m_d3dDevice9 ) ) )
	{
		return false;
	}


	return true;
}


bool GMDirectx9::check_renderer( void )
{
	if( m_d3dDevice9 )
	{
		HRESULT hr = m_d3dDevice9->TestCooperativeLevel();

		switch( hr )
		{
		case D3DERR_DEVICELOST :
		case D3DERR_DEVICENOTRESET :
			{
				if( SUCCEEDED( m_d3dDevice9->Reset( &m_d3dparameter ) ) )
				{
					//! scene again

					return true;
				}				
			}
			return false;

		default :
			return true;
		}
	}

	return false;
}


bool GMDirectx9::begin_scene( unsigned long flag, unsigned long bgclr, float z, unsigned long stencil )
{
	if( m_running && SUCCEEDED( m_d3dDevice9->Clear( 0, 0, flag, bgclr, z, stencil ) ) )
	{
		if( SUCCEEDED( m_d3dDevice9->BeginScene() ) )
		{
			return true;
		}
	}

	return false;
}


void GMDirectx9::end_scene( const RECT* src, const RECT* dest, HWND override_wnd, const RGNDATA* region )
{
	if( m_running )
	{
		m_d3dDevice9->EndScene();
		m_d3dDevice9->Present( src, dest, override_wnd, region );
	}
}